package utils;

import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;

public class Utils {

	/**
	 * Join the list of String with the specified separator
	 * 
	 * @param strings
	 * @param separator
	 * @return
	 */
	public static String join (ArrayList <String> strings, String separator) {
		String res = "" ;
		for (String str : strings) {
			res += separator + str ;
		}
		return res.substring(separator.length()) ;
	}
	
	public interface Extracter <E1, E2> {
		/**
		 * Convert an instance of E1 in an instance of E2
		 */
		public E2 extract (E1 other) ;
	}
	
	
	/**
	 * Extract element of type E2 from element of type E2 using the specified extracter.
	 * 
	 * @param others
	 * @param converter
	 * @return
	 */
	public static <E1, E2>  ArrayList <E2> extract (Collection <E1> others, Extracter <E1, E2> extracter) {
		ArrayList <E2> res = new ArrayList <E2> () ;
		for (E1 o : others) {
			res.add(extracter.extract(o)) ;
		}
		return res ;
	}
	
	/**
	 * Open the specified URL in the default web browser.
	 * 
	 * @param url
	 */
	public static void openURL (String url) {
		try {
			Desktop.getDesktop().browse(new URI(url)) ;
		} 
		catch (Exception e) {
		}
	}
	
	/**
	 * Open the specified file in the appropriate software
	 * 
	 * @param file
	 */
	public static void openFile(String file) {
		try {
			Desktop.getDesktop().open(new File(file)) ;
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public enum OSType {
		WINDOWS,
		MAC,
		LINUX,
		SOLARIS
	}
	
	/**
	 * @return The type of OS (default Linux if nothing found)
	 */
	public static OSType getOSType () {
		String OS = System.getProperty("os.name").toLowerCase() ;
		if (OS.indexOf("win") >= 0) {
			return OSType.WINDOWS ;
		}
		else if (OS.indexOf("mac") >= 0) {
			return OSType.MAC ;
		}
		else if (OS.indexOf("sunos") >= 0) {
			return OSType.SOLARIS ;
		}
		else {
			return OSType.LINUX ;
		}
	}
	
	/**
	 * Get the network address corresponding to the specified address / prefix length
	 * 
	 * @param address The specified address
	 * @param prefixLength The length of the network prefix (in bit)
	 * @return
	 */
	public static InetAddress getNetworkAddress (InetAddress address, int prefixLength) {
		byte[] addr = address.getAddress() ;
		byte[] network = new byte[addr.length] ;
		for (int i=0; i<addr.length; i++) {
			network[i] = 0 ;
			for (int j=0; j<prefixLength; j++) {
				network[i] |= ((0x1 << (8-j-1)) & addr[i]);
			}
			prefixLength -= 8 ;
		}
		InetAddress networkAddress = null ;
		try {
			networkAddress = InetAddress.getByAddress(network) ;
		} 
		catch (UnknownHostException e) {
			e.printStackTrace();
		}
		return networkAddress ;
	}
	
	public static void main (String[] args) throws UnknownHostException {
		String[] addr = {"192.168.2.1", "148.43.12.4", "10.31.45.16"} ;
		int[] prefix = {21, 24, 26} ;
		for (String s: addr) {
			System.out.println(s) ;
			for (int p : prefix) {
				System.out.println(getNetworkAddress(InetAddress.getByName(s), p).getHostAddress() + "/" + p) ;
			}
		}
	}
	
}
